#include "StdAfx.h"
#include "ActiveHSM.h"

namespace RoomFW {

void Q_TRAN_LOG_breakHook()
{
	// Q_TRAN_LOG is implemented as nested macros.  If you need to set a breakpoint, you can do it here.
}

ActiveHSM::ActiveHSM(QSTATE initialState, size_t portCount, const PortPriorityArray& portPriority) :
	QHsm(initialState),
	ActiveObject(portCount, portPriority)
{
}

ActiveHSM::~ActiveHSM(void)
{
}

bool ActiveHSM::initializeThread(void)
{
	QHsm::init(); // Must initialize QHsm.
	return __super::initializeThread(); 
}

void ActiveHSM::handle(RoomMessageSP message)
{
	// Allow derived classes access to the shared pointer.
	currentMessage_ = message;

	// Restore current state on exception.
	currentState_ = this->state_;
	try
	{
		// Call base class dispatch.
		QHsm::dispatch(message.get());
	}
	catch (...)
	{
		// Restore current state before re-throwing.
		this->state_ = currentState_;
		currentMessage_.reset();
		throw;
	}
	currentMessage_.reset();
}

RoomMessageSP ActiveHSM::getCurrentMessage()
{
	return currentMessage_;
}

ActiveHSM::QErrorTranSig::QErrorTranSig(QSTATE dest) :
	dest_(dest)
{
	sig = Q_ERROR_TRAN;
}

void ActiveHSM::errorTran(QSTATE dest)
{
	QHsm::dispatch(&QErrorTranSig(dest));
}

QSTATE ActiveHSM::top(ActiveHSM* me, QEvent const *evt)
{
	QSTATE retVal = reinterpret_cast<QSTATE>(&QHsm::top); // Parent of top-level states.
	switch (evt->sig)
	{
		//
		// Top level state handles Q_ERROR_TRAN to do state transitions from DefaultErrorReporting macros.
		//
	case RoomFW::Q_ERROR_TRAN:
		Q_TRAN(static_cast<const QErrorTranSig*>(evt)->dest_);
		retVal = 0;
		break;
	}
	return retVal;
}

QSTATE ActiveHSM::getCurrentState()
{
	return currentState_;
}

}
